package com.gitee.feizns.web.crud;

import com.gitee.feizns.bean.Convertible;
import com.gitee.feizns.reflect.ClassUtils;
import com.gitee.feizns.reflect.ConstructorUtils;
import com.gitee.feizns.web.dao.ar.AbstractModel;
import com.gitee.feizns.web.domain.page.PageAo;
import com.gitee.feizns.web.domain.page.PageVoRet;

import java.io.Serializable;

/**
 * @author feizns
 * @since 2019/11/1
 */
public interface ModelService<M extends AbstractModel<M>, LV, DV, PK extends Serializable, LA, CA extends Convertible, UA extends Convertible> {

    /**
     * 列表
     * @param page
     * @param ao
     * @return
     */
    default PageVoRet<LV> list(PageAo page, LA ao) {
        return ConstructorUtils.newInstance(getModel()).selectPage(getLv(), page, ao);
    }

    /**
     * 详情
     * @param pk
     * @return
     */
    default DV details(PK pk) {
        return ConstructorUtils.newInstance(getModel()).selectByPk(getDv(), pk);
    }

    /**
     * 创建
     * @param ao
     * @return
     */
    default DV create(CA ao) {
        return details((PK) ao.to(getModel()).create());
    }

    /**
     * 修改
     * @param pk
     * @param ao
     * @return
     */
    default DV update(PK pk, UA ao) {
        return details((PK) ao.to(getModel()).updateByPk(pk));
    }

    /**
     * 删除
     * @param pk
     */
    default void delete(PK pk) {
        ConstructorUtils.newInstance(getModel()).deleteById(pk);
    }

    /**
     * 模型类
     * @return
     */
    default Class<M> getModel() {
        return (Class<M>) ClassUtils.getInterfaceGenericTypes(getMarkGenericType(), ModelService.class)[0];
    }

    /**
     * 列表展示对象类型
     * @return
     */
    default Class<LV> getLv() {
        return (Class<LV>) ClassUtils.getInterfaceGenericTypes(getMarkGenericType(), ModelService.class)[1];
    }

    /**
     * 详情展示对象类型
     * @return
     */
    default Class<DV> getDv() {
        return (Class<DV>) ClassUtils.getInterfaceGenericTypes(getMarkGenericType(), ModelService.class)[2];
    }

    /**
     * 获取标记了泛型的类
     * @return
     */
    default Class<?> getMarkGenericType() {
        return this.getClass().getInterfaces()[0];
    }

}

